/* frame.h */
#ifndef __FRAME_H__
#define __FRAME_H__


typedef struct F_frame_ *F_frame;
typedef struct F_access_ *F_access;
typedef struct F_accessList_ *F_accessList;

struct F_frame_
{
	Temp_label name;
	F_accessList formals;
	F_accessList locals;
	int local_count;
};

struct F_access_
{
	enum { inFrame, inReg } kind;
	union {
		int offset; // inframe
		Temp_temp reg; // inreg
	} u;
};
struct F_accessList_ { 
	F_access head; 
	F_accessList tail; 
};
F_access InFrame(int offset);
F_access InReg(Temp_temp reg);
F_accessList F_AccessList(F_access head, F_accessList tail);

Temp_label F_name(F_frame f);
F_accessList F_Formals(F_frame f);
F_access F_allocLocal(F_frame f, bool escape);
int F_getoffset(F_access acs);
extern const int WORD_SIZE;

//// Fragments

typedef struct F_frag_ *F_frag;
struct F_frag_ {
	enum {F_stringFrag, F_procFrag } kind;
	union {
		struct {
			Temp_label label;
			string str;
		} stringg;
		struct {
			T_stm stmbody;
			F_frame frame;
		} proc;
	} u;
};

F_frag F_StringFrag(Temp_label label, string str);
F_frag F_ProcFrag(T_stm body, F_frame frame);

typedef struct F_fragList_ *F_fragList;
struct F_fragList_ {
	F_frag head;
	F_fragList tail;
};
F_fragList F_FragList(F_frag head, F_fragList tail);


Temp_temp F_FP(void);
//Temp_temp F_SP(void);
//Temp_temp F_ZERO(void);
//Temp_temp F_RA(void);
Temp_temp F_RV(void);

//Temp_map F_tempMap;
//Temp_tempList F_registers(void); 
//string F_getlabel(F_frame frame);
T_exp F_Exp(F_access acs, T_exp framePtr);

F_frame F_newFrame(Temp_label name, F_accessList formals);
T_exp F_externalCall(string s, T_expList args);
//F_frag F_string(Temp_label label, string str);
//F_frag F_newProcFrag(T_stm body, F_frame frame);
T_stm F_procEntryExit1(F_frame frame, T_stm stm);


#endif //!__FRAME_H__